"""
Celery tasks used by the `course_home_api` app.
"""
import logging

from celery import shared_task
from django.contrib.auth import get_user_model
from edx_django_utils.monitoring import set_code_owner_attribute
from eventtracking import tracker
from opaque_keys import InvalidKeyError
from opaque_keys.edx.keys import CourseKey

from common.djangoapps.student.models_api import get_course_enrollment
from lms.djangoapps.course_home_api.progress.api import calculate_progress_for_learner_in_course

User = get_user_model()
COURSE_COMPLETION_FOR_USER_EVENT_NAME = "edx.bi.user.course-progress"

log = logging.getLogger(__name__)


@shared_task
@set_code_owner_attribute
def collect_progress_for_user_in_course(course_id: str, user_id: str) -> None:
    """
    Celery task that retrieves a learner's progress in a given course.
    """
    try:
        course_key = CourseKey.from_string(course_id)
    except InvalidKeyError:
        log.warning(f"Invalid course id {course_id}, aborting task.")
        return

    try:
        user = User.objects.get(id=user_id)
    except User.DoesNotExist:
        log.warning(f"Could not retrieve a user with id {user_id}, aborting task.")
        return

    try:
        enrollment = get_course_enrollment(user, course_key)
        enrollment_mode = enrollment.mode
    except AttributeError:
        log.warning(f"Could not retrieve enrollment info for user {user.id} in course {course_id}")
        return

    progress = calculate_progress_for_learner_in_course(course_key, user)

    # add a few extra fields to the returned data to make the event payload a bit more usable
    progress["user_id"] = user.id
    progress["course_id"] = course_id
    progress["enrollment_mode"] = enrollment_mode

    context = {
        "course_id": course_id,
        "user_id": user.id,
    }
    with tracker.get_tracker().context(COURSE_COMPLETION_FOR_USER_EVENT_NAME, context):
        tracker.emit(
            COURSE_COMPLETION_FOR_USER_EVENT_NAME,
            progress
        )
